﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DTBuilderLib;
using DTBuilderLib.VisualHierarchyClasses;
using System.IO;
using IndicoInterface;
using IndicoInterface.SimpleAgendaDataModel;

namespace t_DTBuilderLib
{
    /// <summary>
    /// Summary description for t_LayoutBuilder
    /// </summary>
    [TestClass]
    public class t_LayoutBuilder
    {
        public t_LayoutBuilder()
        {
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void TestLayoutCTor()
        {
            LayoutBuilder_Accessor lb = new LayoutBuilder_Accessor();
            Assert.IsTrue(lb.DPI == 600, "DPI not right");
            Assert.IsTrue(lb.XBoarderSize == 0.2F, "x boarder size not right");
            Assert.IsTrue(lb.YBoarderSize == 0.2F, "y boarder size not right");
        }

        [TestMethod]
        public void TestLayoutOneSlide()
        {
            LayoutBuilder_Accessor lb = new LayoutBuilder_Accessor();
            List<FileInfo> slides = new List<FileInfo>();
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            var result = lb.BuildVisualTreeForTalkSlides(slides);

            Assert.IsTrue(result.Width == 10.0F, "Width of talk is not right");
            Assert.IsTrue(result.Height == 7.5F, "Height of talk is not right");
            Assert.IsTrue(result.XPosition == 0, "X pos is not right");
            Assert.IsTrue(result.YPosition == 0, "Y pos is not right");
        }

        [TestMethod]
        public void TestLayoutTwoSlide()
        {
            LayoutBuilder_Accessor lb = new LayoutBuilder_Accessor();
            List<FileInfo> slides = new List<FileInfo>();
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            var result = lb.BuildVisualTreeForTalkSlides(slides);

            Assert.IsTrue(result.Width == 20.2F, "Width of talk is not right");
            Assert.IsTrue(result.Height == 7.5F, "Height of talk is not right");
            Assert.IsTrue(result.XPosition == 0, "X pos is not right");
            Assert.IsTrue(result.YPosition == 0, "Y pos is not right");
        }
        [TestMethod]
        public void TestLayoutThreeSlide()
        {
            LayoutBuilder_Accessor lb = new LayoutBuilder_Accessor();
            List<FileInfo> slides = new List<FileInfo>();
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            var result = lb.BuildVisualTreeForTalkSlides(slides);

            Assert.IsTrue(result.Width == (10.2F*3F-0.2F), "Width of talk is not right");
            Assert.IsTrue(result.Height == 7.5F, "Height of talk is not right");
            Assert.IsTrue(result.XPosition == 0, "X pos is not right");
            Assert.IsTrue(result.YPosition == 0, "Y pos is not right");
        }
        [TestMethod]
        public void TestLayoutFourSlide()
        {
            LayoutBuilder_Accessor lb = new LayoutBuilder_Accessor();
            List<FileInfo> slides = new List<FileInfo>();
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            var result = lb.BuildVisualTreeForTalkSlides(slides);

            Assert.IsTrue(result.Width == (10.2F * 4F - 0.2F), "Width of talk is not right");
            Assert.IsTrue(result.Height - 7.5 < 0.01F, "Height of talk is not right");
            Assert.IsTrue(result.XPosition == 0, "X pos is not right");
            Assert.IsTrue(result.YPosition == 0, "Y pos is not right");
        }
        [TestMethod]
        public void TestLayoutFiveSlide()
        {
            LayoutBuilder_Accessor lb = new LayoutBuilder_Accessor();
            List<FileInfo> slides = new List<FileInfo>();
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            var result = lb.BuildVisualTreeForTalkSlides(slides);

            Assert.IsTrue(result.Width == (10.2F * 5F - 0.2F), "Width of talk is not right");
            Assert.IsTrue(result.Height - 7.5 < 0.01F, "Height of talk is not right");
            Assert.IsTrue(result.XPosition == 0, "X pos is not right");
            Assert.IsTrue(result.YPosition == 0, "Y pos is not right");
        }

        [TestMethod]
        public void TestLayoutOneTalk()
        {
            List<FileInfo> slides = new List<FileInfo>();
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));

            LayoutBuilder_Accessor bld = new LayoutBuilder_Accessor();
            Visual v = bld.BuildVisualTreeForATalk("This is the title", "a1281", "This is the author and time string", slides);

            var data = v.SGNodeList;
            FileInfo background = new FileInfo(data[0].FileName);
            int[] size = TestUtilities.GetImageSize(background);
            Assert.IsTrue(size[0] > 600, "Background image is too small! Makes no sense!");
            Assert.IsTrue(size[1] > 600, "Background image is too small! Makes no sense!");

            Assert.IsTrue(v.IsCompositionUnit, "The talk should have been marked as a composition unit");

            Assert.AreEqual("This is the title", v.Title, "Title hasn't been set correctly");
            Assert.AreEqual("a1281", v.ShortName, "The short name hasn't been set correctly");
        }

        [TestMethod]
        public void TestLayoutTooLongTalk()
        {
            ///
            /// If a talk has too many slides than the SPI code chokes with too much memory. So the code
            /// is designed to split it up - this will test that splitting to make sure it happens.
            /// 

            List<FileInfo> slides = new List<FileInfo>();
            for (int i = 0; i < 70; i++)
            {
                slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            }

            LayoutBuilder_Accessor bld = new LayoutBuilder_Accessor();
            Visual v = bld.BuildVisualTreeForATalk("This is the title", "a1281", "This is the author and time string", slides);

            Assert.IsFalse(v.IsCompositionUnit, "The talk is too big to be a single composition unit!");
            /// Number of rendering units here:
            /// 1 - title
            /// 1 - background
            /// 1 - first three rows of slides
            /// 1 - second three rows of slides
            /// 1 - third three rows of slides
            Assert.AreEqual(5, v.GetHierarchicalEnumerator(mv => mv.IsCompositionUnit).Count(), "Wrong number of rendering units for the talk!");

            foreach (var av in v.GetHierarchicalEnumerator(mv => mv.IsCompositionUnit))
            {
                Assert.IsTrue(av.ShortNameGood, "Short name is not good for an image we are going to generate here!");
            }
        }

        [TestMethod]
        public void TestLayoutBigTalk()
        {
            /// Looking for a bunch of vertical arrangements :-).
            LayoutBuilder_Accessor lb = new LayoutBuilder_Accessor();
            List<FileInfo> slides = new List<FileInfo>();
            for (int i = 0; i < 24; i++)
            {
                slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            }

            LayoutBuilder_Accessor bld = new LayoutBuilder_Accessor();
            Visual v = bld.BuildVisualTreeForATalk("This is the title", "a1234", "This is the info string", slides);

            var data = v.SGNodeList;
            FileInfo background = new FileInfo(data[0].FileName);
            int[] size = TestUtilities.GetImageSize(background);
            Assert.IsTrue(size[0] > 600, "Background image is too small! Makes no sense!");
            Assert.IsTrue(size[1] > 600, "Background image is too small! Makes no sense!");

            Assert.IsTrue(data.Count(im => im.Width < 2.0) == 24, "Incorect number of images smaller than 2.0");
            Assert.IsTrue(data.Count(im => im.Width >= 0.7) == 26, "Incorect number of images not larger than 1.0!");

            var titleSlide = data[1];
            var backgroundSlide = data[0];
            Assert.IsTrue(titleSlide.Width - backgroundSlide.Width < 0.41, "Title slide is too small - should take up everything!");
        }

        [TestMethod]
        public void TestLayout20Talk()
        {
            /// Looking for a bunch of vertical arrangements :-).
            LayoutBuilder_Accessor lb = new LayoutBuilder_Accessor();
            List<FileInfo> slides = new List<FileInfo>();
            for (int i = 0; i < 20; i++)
            {
                slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            }

            LayoutBuilder_Accessor bld = new LayoutBuilder_Accessor();
            Visual v = bld.BuildVisualTreeForATalk("This is the title", "a1234", "This is the info string", slides);

            var data = v.SGNodeList;
            FileInfo background = new FileInfo(data[0].FileName);
            int[] size = TestUtilities.GetImageSize(background);
            Assert.IsTrue(size[0] > 600, "Background image is too small! Makes no sense!");
            Assert.IsTrue(size[1] > 600, "Background image is too small! Makes no sense!");

            Assert.IsTrue(data.Count(im => im.Width < 2.0) == 20, "Incorect number of images smaller than 2.0");

            var titleSlide = data[1];
            var backgroundSlide = data[0];
            Assert.IsTrue(titleSlide.Width - backgroundSlide.Width < 0.41, "Title slide is too small - should take up everything!");
        }

        [TestMethod]
        public void TestLayoutOneSmallSlideTalk()
        {
            /// Try layout of a talk that has one slide -- but it is one of those small TeX slides. :(
            LayoutBuilder_Accessor lb = new LayoutBuilder_Accessor();
            List<FileInfo> slides = new List<FileInfo>();
            slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\texSmallSlide.jpg"));
            var result = lb.BuildVisualTreeForATalk("This is the title", "a1234", "This is the info string", slides);

            Assert.IsTrue(result.Width == 10.0F + 0.4F, "Width of talk is not right");
            Assert.IsTrue(result.Height == 7.5F + 1.0F + 0.4F, "Height of talk is not right");
            Assert.IsTrue(result.XPosition == 0, "X pos is not right");
            Assert.IsTrue(result.YPosition == 0, "Y pos is not right");
        }

        [TestMethod]
        public void TestLayoutSmallSlideTalk()
        {
            /// Try layout of a talk that has one slide -- but it is one of those small TeX slides. :(
            LayoutBuilder_Accessor lb = new LayoutBuilder_Accessor();
            List<FileInfo> slides = new List<FileInfo>();
            for (int i = 0; i < 28; i++)
            {
                slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\texSmallSlide.jpg"));
            }

            var result = lb.BuildVisualTreeForATalk("This is the title", "a1234", "This is the info string", slides);

            double deltaLeft = TalkSlideLeftMargin(result);
            Assert.IsTrue(deltaLeft < 1.0F, "Talk slides are more than 1 inch away from the edge of the title slide");
            Assert.IsTrue(deltaLeft >= -0.01F, "Talk slides shouldn't be larger than the title slide!");
        }

        [TestMethod]
        public void TestLayoutSmall8SlideTalk()
        {
            /// Try layout of a talk that has one slide -- but it is one of those small TeX slides. :(
            LayoutBuilder_Accessor lb = new LayoutBuilder_Accessor();
            List<FileInfo> slides = new List<FileInfo>();
            for (int i = 0; i < 8; i++)
            {
                slides.Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\texSmallSlide.jpg"));
            }

            var result = lb.BuildVisualTreeForATalk("This is the title", "a1234", "This is the info string", slides);

            double deltaLeft = TalkSlideLeftMargin(result);
            Assert.IsTrue(deltaLeft > 0.5F, "Talk slides are less than 1 inch away from the edge of the title slide");
        }

        /// <summary>
        /// Calculate the delta between the left margin of the first slide and the title.
        /// We depend on the order of the slides that were inserted in this visual tree - so we
        /// are pretty fragile.
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        private double TalkSlideLeftMargin(Visual result)
        {
            var asone = result.SGNodeList;
            Assert.IsTrue(asone.Count > 3, "Not enough slides to do the test");
            double titleLeft = asone[1].x;
            double firstLeft = asone[2].x;
            return firstLeft - titleLeft;
        }

#if false
        /// THis is now a password protected meeting.
        [TestMethod]
        public void TestLayoutSession()
        {
            /// Render a talk that we have downloaded.
            JobDownloader jd = new JobDownloader();
            AgendaInfo a = new AgendaInfo(33078);
            var data = jd.DownloadMeeting(a.GetNormalizedConferenceData());
            Assert.IsTrue(data.Sessions.Length == 1, "More than one session for this test -- that is bad!");

            JPEGRender r = new JPEGRender();
            var renderedSlides = r.RenderMeeting(data);

            var talks = from s in data.Sessions
                        from t in s.Talks
                        where t.SlideURL != null
                        where t.SlideURL.Length != 0
                        select t;

            LayoutBuilder_Accessor bld = new LayoutBuilder_Accessor();
            Visual v = bld.BuildVisualTreeForASession("Test Session", data.Sessions[0].StartDate, data.Sessions[0].EndDate, talks.ToArray(), renderedSlides);
            var sgslides = v.SGNodeList;

            Assert.IsTrue(sgslides[0].Height < 12.0, "Seems like more than one row of talks.. not right");
        }
#endif

        [TestMethod]
        public void TestNullTalksInSession()
        {
            /// Mal formed input shoudl be dealt with if just leaving off talks in a session.
            Meeting m = new Meeting();
            m.Title = "This is a meeting";
            m.ID = "10";
            m.StartDate = DateTime.Now;
            m.EndDate = DateTime.Now;

            Session s1 = new Session();
            s1.EndDate = DateTime.Now;
            s1.StartDate = DateTime.Now;
            s1.ID = "5";
            s1.Title = "Session 1";
            s1.Talks = null;

            m.Sessions = new Session[] { s1 };

            LayoutBuilder bld = new LayoutBuilder();
            var data = bld.BuildVisualTreeForAMeeting(m, new Dictionary<Talk,List<FileInfo>>());
            Assert.IsTrue(data == null, "Null meeting with no talks!!");
        }

        [TestMethod]
        public void TestSingleSessionMeeting()
        {
            Assert.Fail("Test not written yet");
        }

        [TestMethod]
        public void TestTwoNullSessions()
        {
            /// Mal formed input shoudl be dealt with if just leaving off talks in a session.
            Meeting m = new Meeting();
            m.Title = "This is a meeting";
            m.ID = "10";
            m.StartDate = DateTime.Now;
            m.EndDate = DateTime.Now;

            Session s1 = new Session();
            s1.EndDate = DateTime.Now;
            s1.StartDate = DateTime.Now;
            s1.ID = "5";
            s1.Title = "Session 1";
            s1.Talks = null;

            Session s2 = new Session();
            s2.EndDate = DateTime.Now;
            s2.StartDate = DateTime.Now;
            s2.ID = "6";
            s2.Title = "Session 2";
            s2.Talks = null;

            m.Sessions = new Session[] { s1, s2 };

            LayoutBuilder bld = new LayoutBuilder();
            var data = bld.BuildVisualTreeForAMeeting(m, new Dictionary<Talk, List<FileInfo>>());
            Assert.IsTrue(data == null, "Null meeting with no talks has rendered slides!!");
        }

        [TestMethod]
        public void TestTwoNullSessionsWithArrayReferences()
        {
            /// Mal formed input shoudl be dealt with if just leaving off talks in a session.
            Meeting m = new Meeting();
            m.Title = "This is a meeting";
            m.ID = "10";
            m.StartDate = DateTime.Now;
            m.EndDate = DateTime.Now;

            Session s1 = new Session();
            s1.EndDate = DateTime.Now;
            s1.StartDate = DateTime.Now;
            s1.ID = "5";
            s1.Title = "Session 1";
            s1.Talks = new Talk[0];

            Session s2 = new Session();
            s2.EndDate = DateTime.Now;
            s2.StartDate = DateTime.Now;
            s2.ID = "6";
            s2.Title = "Session 2";
            s2.Talks = new Talk[0];

            m.Sessions = new Session[] { s1, s2 };

            LayoutBuilder bld = new LayoutBuilder();
            var data = bld.BuildVisualTreeForAMeeting(m, new Dictionary<Talk, List<FileInfo>>());
            Assert.IsTrue(data == null, "Null meeting with no talks has rendered slides!!");
        }

        [TestMethod]
        public void TestTwoNullSessionsWithTalkReferences()
        {
            /// Mal formed input shoudl be dealt with if just leaving off talks in a session.
            Meeting m = new Meeting();
            m.Title = "This is a meeting";
            m.ID = "10";
            m.StartDate = DateTime.Now;
            m.EndDate = DateTime.Now;

            Talk t1 = new Talk() { EndDate = DateTime.Now, StartDate = DateTime.Now, ID = "5", Speakers = null, Title = "hithere" };

            Session s1 = new Session();
            s1.EndDate = DateTime.Now;
            s1.StartDate = DateTime.Now;
            s1.ID = "5";
            s1.Title = "Session 1";
            s1.Talks = new Talk[] { t1 };

            Talk t2 = new Talk() { EndDate = DateTime.Now, StartDate = DateTime.Now, ID = "6", Speakers = null, Title = "hithere dude" };

            Session s2 = new Session();
            s2.EndDate = DateTime.Now;
            s2.StartDate = DateTime.Now;
            s2.ID = "6";
            s2.Title = "Session 2";
            s2.Talks = new Talk[] { t2 };

            m.Sessions = new Session[] { s1, s2 };

            Dictionary<Talk, List<FileInfo>> slides = new Dictionary<Talk, List<FileInfo>>();
            slides[t1] = new List<FileInfo>();
            slides[t2] = new List<FileInfo>();

            LayoutBuilder bld = new LayoutBuilder();
            var data = bld.BuildVisualTreeForAMeeting(m, slides);
            Assert.IsTrue(data == null, "Null meeting with no talks has rendered slides!!");
        }

        [TestMethod]
        public void TestTwoSessionOneNull()
        {
            /// Mal formed input shoudl be dealt with if just leaving off talks in a session.
            Meeting m = new Meeting();
            m.Title = "This is a meeting";
            m.ID = "10";
            m.StartDate = DateTime.Now;
            m.EndDate = DateTime.Now;

            Session s1 = new Session();
            s1.EndDate = DateTime.Now;
            s1.StartDate = DateTime.Now;
            s1.ID = "5";
            s1.Title = "Session 1";
            s1.Talks = null;

            Talk t = new Talk() { EndDate = DateTime.Now, StartDate = DateTime.Now, ID = "1", Title = "hi there", Speakers = null };
            Dictionary<Talk, List<FileInfo>> slides = new Dictionary<Talk, List<FileInfo>>();
            slides[t] = new List<FileInfo>();
            slides[t].Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\texSmallSlide.jpg"));

            Session s2 = new Session();
            s2.EndDate = DateTime.Now;
            s2.StartDate = DateTime.Now;
            s2.ID = "6";
            s2.Title = "Session 2";
            s2.Talks = new Talk[] { t };

            m.Sessions = new Session[] { s1, s2 };

            LayoutBuilder bld = new LayoutBuilder();
            var data = bld.BuildVisualTreeForAMeeting(m, slides);
            Assert.IsTrue(data != null, "Null meeting with no talks has rendered slides!!");

            Assert.AreEqual("This is a meeting", data.Title, "Title of meeting isn't right");
            Assert.AreEqual("10", data.ShortName, "The short name of the meeting isn't right");

            var visuals = from v in data.GetHierarchicalEnumerator(v => v.IsCompositionUnit)
                          select v;
            var visualsArray = visuals.ToArray();

            foreach (var v in visualsArray)
            {
                Assert.AreEqual(true, v.ShortNameGood, "Short name is not good for this visual!");
            }

            var visualList = data.SGNodeList;
            Assert.IsTrue(visualList.Count == 4, "Wrong number of visuals for one talk in one session in one meeting");
        }

        [TestMethod]
        public void TestThreeSessionTwoNull()
        {
            /// Mal formed input shoudl be dealt with if just leaving off talks in a session.
            Meeting m = new Meeting();
            m.Title = "This is a meeting";
            m.ID = "10";
            m.StartDate = DateTime.Now;
            m.EndDate = DateTime.Now;

            Session s1 = new Session();
            s1.EndDate = DateTime.Now;
            s1.StartDate = DateTime.Now;
            s1.ID = "5";
            s1.Title = "Session 1";
            s1.Talks = null;

            Talk t = new Talk() { EndDate = DateTime.Now, StartDate = DateTime.Now, ID = "1", Title = "hi there", Speakers = null };
            Dictionary<Talk, List<FileInfo>> slides = new Dictionary<Talk, List<FileInfo>>();
            slides[t] = new List<FileInfo>();
            slides[t].Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\texSmallSlide.jpg"));

            Session s2 = new Session();
            s2.EndDate = DateTime.Now;
            s2.StartDate = DateTime.Now;
            s2.ID = "6";
            s2.Title = "Session 2";
            s2.Talks = new Talk[] { t };

            Session s3 = new Session();
            s3.EndDate = DateTime.Now;
            s3.StartDate = DateTime.Now;
            s3.ID = "7";
            s3.Title = "Session 3";
            s3.Talks = new Talk[0];

            m.Sessions = new Session[] { s1, s2, s3 };

            LayoutBuilder bld = new LayoutBuilder();
            var data = bld.BuildVisualTreeForAMeeting(m, slides);
            Assert.IsTrue(data != null, "Null meeting with no talks has rendered slides!!");
            var visualList = data.SGNodeList;
            Assert.IsTrue(visualList.Count == 4, "Wrong number of visuals for one talk in one session in one meeting");
        }

        [TestMethod]
        public void TestLayoutTalkNullMultiSession()
        {
            /// Make sure that empty sessions don't participate!

            Meeting m = new Meeting();
            m.Title = "This is a meeting";
            m.ID = "10";
            m.StartDate = DateTime.Now;
            m.EndDate = DateTime.Now;

            Session s1 = new Session();
            s1.EndDate = DateTime.Now;
            s1.StartDate = DateTime.Now;
            s1.ID = "5";
            s1.Title = "Session 1";

            Session s2 = new Session();
            s2.EndDate = DateTime.Now;
            s2.StartDate = DateTime.Now;
            s2.ID = "6";
            s2.Title = "Session 1";

            Talk t1 = new Talk();
            t1.EndDate = DateTime.Now;
            t1.StartDate = DateTime.Now;
            t1.ID = "7";
            t1.SlideURL = "c:\\bogus\\dude.pdf";
            t1.Speakers = new string[] { "Gordon Watts" };
            t1.Title = "Talk 1";

            Talk t2 = new Talk();
            t2.EndDate = DateTime.Now;
            t2.StartDate = DateTime.Now;
            t2.ID = "7";
            t2.SlideURL = "c:\\bogus\\dude.pdf";
            t2.Speakers = new string[] { "Gordon Watts" };
            t2.Title = "Talk 1";

            s1.Talks = new Talk[] { t1, t2 };
            m.Sessions = new Session[] { s1, s2 };

            FileInfo aslide = new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg");
            Dictionary<Talk, List<FileInfo>> slides = new Dictionary<Talk, List<FileInfo>>();
            slides[t1] = new List<FileInfo>();
            slides[t1].Add(aslide);
            slides[t1].Add(aslide);

            slides[t2] = new List<FileInfo>();
            slides[t2].Add(aslide);
            slides[t2].Add(aslide);

            LayoutBuilder layout = new LayoutBuilder();
            var data = layout.BuildVisualTreeForAMeeting(m, slides);
        }

        [TestMethod]
        public void TestLayoutReallyBigSlides()
        {
            /// A slide so big and so many pixels that is could be causing us a problem
            /// with width if we don't "shrink" it first.

            FileInfo bigslide = new FileInfo("..\\..\\..\\t_DTBuilderLib\\file-big.jpg");
            Assert.IsTrue(bigslide.Exists, "Big file jpeg doesn't exist");

            List<FileInfo> slides = new List<FileInfo>();
            int nslides = 30;
            for (int i = 0; i < nslides; i++)
            {
                slides.Add(bigslide);
            }

            LayoutBuilder_Accessor lay = new LayoutBuilder_Accessor();
            lay.DPI = 300;
            var v = lay.BuildVisualTreeForATalk("my title", "a1234", "what talk??", slides);

            var rendered = v.SGNodeList;
            Assert.IsTrue(rendered.Count == nslides+2, "Wrong number of images output for talk!");

        }

        [TestMethod]
        public void TestLayoutSingleSlideTalk()
        {
            /// If there is only one slide, we shouldn't do much with it!
            /// A slide so big and so many pixels that is could be causing us a problem
            /// with width if we don't "shrink" it first.

            FileInfo bigslide = new FileInfo("..\\..\\..\\t_DTBuilderLib\\file-big.jpg");
            Assert.IsTrue(bigslide.Exists, "Big file jpeg doesn't exist");

            List<FileInfo> slides = new List<FileInfo>();
            slides.Add(bigslide);

            LayoutBuilder_Accessor lay = new LayoutBuilder_Accessor();
            lay.DPI = 300;
            var v = lay.BuildVisualTreeForATalk("my title", "a1234", "what talk??", slides);

            var rendered = v.SGNodeList;
            Assert.IsTrue(rendered.Count == 2, "Wrong number of images - should have only a single slide!!");
        }

        [TestMethod]
        public void TestLayoutEmptySession()
        {
            /// Make sure that empty sessions don't participate!

            Meeting m = new Meeting();
            m.Title = "This is a meeting";
            m.ID = "10";
            m.StartDate = DateTime.Now;
            m.EndDate = DateTime.Now;

            Session s1 = new Session();
            s1.EndDate = DateTime.Now;
            s1.StartDate = DateTime.Now;
            s1.ID = "5";
            s1.Title = "Session 1";

            Session s2 = new Session();
            s2.EndDate = DateTime.Now;
            s2.StartDate = DateTime.Now;
            s2.ID = "6";
            s2.Title = "Session 1";

            Talk t1 = new Talk();
            t1.EndDate = DateTime.Now;
            t1.StartDate = DateTime.Now;
            t1.ID = "7";
            t1.SlideURL = "c:\\bogus\\dude.pdf";
            t1.Speakers = new string[] { "Gordon Watts" };
            t1.Title = "Talk 1";

            Talk t2 = new Talk();
            t2.EndDate = DateTime.Now;
            t2.StartDate = DateTime.Now;
            t2.ID = "7";
            t2.SlideURL = "c:\\bogus\\dude.pdf";
            t2.Speakers = new string[] { "Gordon Watts" };
            t2.Title = "Talk 1";

            s1.Talks = new Talk[] { t1, t2 };
            s2.Talks = new Talk[0];
            m.Sessions = new Session[] { s1, s2 };

            FileInfo aslide = new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg");
            Dictionary<Talk, List<FileInfo>> slides = new Dictionary<Talk, List<FileInfo>>();
            slides[t1] = new List<FileInfo>();
            slides[t1].Add(aslide);
            slides[t1].Add(aslide);

            slides[t2] = new List<FileInfo>();
            slides[t2].Add(aslide);
            slides[t2].Add(aslide);

            LayoutBuilder layout = new LayoutBuilder();
            var data = layout.BuildVisualTreeForAMeeting(m, slides);

            /// # of visual images we should see:
            /// 1 - Meeting background
            /// 1 - Session 1 background
            /// 1 - Talk 1 background
            /// 3 - Talk 1 slides (title slide, and then both slides again).
            /// 1 - Talk 2 background
            /// 3 - Talk 2 slides
            /// 
            /// Total = 10

            Assert.IsTrue(data.SGNodeList.Count == 10, "Wrong number of graphical images made!");
        }

#if false
        /// Meeting is now protected.
        [TestMethod]
        public void TestLayoutMeetingSmall()
        {
            /// Render a talk that we have downloaded.
            JobDownloader jd = new JobDownloader();
            AgendaInfo a = new AgendaInfo(33078);
            var data = jd.DownloadMeeting(a.GetNormalizedConferenceData());
            Assert.IsTrue(data.Sessions.Length == 1, "More than one session for this test -- that is bad!");

            JPEGRender r = new JPEGRender();
            var renderedSlides = r.RenderMeeting(data);

            LayoutBuilder_Accessor bld = new LayoutBuilder_Accessor();
            Visual v = bld.BuildVisualTreeForAMeeting(data, renderedSlides);
            var sgslides = v.SGNodeList;

            Assert.IsTrue(sgslides[0].Height < 12.0, "Seems like only one row of talks.. not right");
        }
#endif

#if false
        /// Meeting is now protected by password.

        [TestMethod]
        public void TestLayoutMeetingLarge()
        {
            /// Render a talk that we have downloaded.
            JobDownloader jd = new JobDownloader();
            AgendaInfo a = new AgendaInfo(14475);
            var data = jd.DownloadMeeting(a.GetNormalizedConferenceData());
            Assert.IsTrue(data.Sessions.Length > 1, "Should be more than one session for this test -- that is bad!");

            JPEGRender r = new JPEGRender();
            var renderedSlides = r.RenderMeeting(data);

            LayoutBuilder_Accessor bld = new LayoutBuilder_Accessor();
            Visual v = bld.BuildVisualTreeForAMeeting(data, renderedSlides);
            var sgslides = v.SGNodeList;

            Assert.IsTrue(sgslides.Count > 100, "Not enough slides in this meeting!");
        }
#endif
        [TestMethod]
        public void TestCrazyBigMeeting()
        {
            /// We saw a crash in a 1-session meeting that had some large number of talks. 
            /// Due to creating a title slide that is too big.
            /// 

            LayoutBuilder_Accessor lb = new LayoutBuilder_Accessor();
            Meeting m = new Meeting();
            m.Title = "hi";
            Session s = new Session();
            s.Title = "yo";
            
            List<Talk> talks = new List<Talk>();
            Dictionary<Talk, List<FileInfo>> slides = new Dictionary<Talk,List<FileInfo>>();
            for (int i = 0; i < 50; i++)
            {
                Talk t = new Talk() { Title = "a talk" };
                t.SlideURL = "bogus";
                talks.Add(t);
                slides[t] = new List<FileInfo>();
                slides[t].Add(new FileInfo("..\\..\\..\\t_DTBuilderLib\\file1.jpg"));
            }
            s.Talks = talks.ToArray();
            m.Sessions = new Session[] { s };

            var result = lb.BuildVisualTreeForAMeeting(m, slides);
            var boom = result.SGNodeList;
        }

        [TestMethod]
        public void Test2x3TwoItemLayout()
        {
            /// Make sure that if we request 2:3, that the layout is horizontal.
            
            LayoutBuilder_Accessor lay = new LayoutBuilder_Accessor();
            int ncols = lay.CalculateNumberOfColunms2x3(2);
            Assert.IsTrue(ncols == 2, "Incorrect number of columns for a simple 2 slide talk/session");
        }

        [TestMethod]
        public void TestColumnCloseToCalc()
        {
            /// THis layout guy shoudl try to get close to the number of columns we ask for, without making
            /// things really lopsided. So it is a bit fuzzy and probably subjective if it is actually
            /// working. No justify here! :-) Max varience is 20%.
            LayoutBuilder_Accessor lay = new LayoutBuilder_Accessor();

            Assert.IsTrue(2 == lay.CalcColumnsCloseToTarget(2, 10), "Short talk doesn't come out right length");
            Assert.IsTrue(10 == lay.CalcColumnsCloseToTarget(10, 10), "Short talk doesn't come out right length");
            Assert.IsTrue(10 == lay.CalcColumnsCloseToTarget(20, 10), "Easy talk doesn't come out right.");

            Assert.IsTrue(11 == lay.CalcColumnsCloseToTarget(11, 10), "Layout of 15 slides isn't right");
            Assert.IsTrue(9 == lay.CalcColumnsCloseToTarget(27, 10), "Layout of 27 should have been 9 which is evenly divisible");
            Assert.IsTrue(8 == lay.CalcColumnsCloseToTarget(15, 10), "Layout of 27 should have been 9 which is evenly divisible");
            Assert.IsTrue(7 != lay.CalcColumnsCloseToTarget(21, 10), "Layout of 21 (which would like to be 7) can't because it is too big a change.");
        }
    }
}
